
/*
 * Copyright 2002-2021 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*
 *版权所有2002-2021原作者。
 *
 *根据Apache许可证2.0版许可（“许可证”）；
 *除非符合许可证的规定，否则您不得使用此文件。
 *您可以在以下网址获取许可证副本：
 *
 *https://www.apache.org/licenses/LICENSE-2.0
 *
 *除非适用法律要求或书面同意，软件
 *根据许可证进行的分发是在“按原样”的基础上进行的，
 *无任何明示或暗示的保证或条件。
 *有关管理权限的特定语言，请参阅许可证和
 *许可证下的限制。
 */

package org.springframework.scheduling.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.concurrent.Executor;

import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.scheduling.Trigger;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;

/**
 * Enables Spring's scheduled task execution capability, similar to
 * functionality found in Spring's {@code <task:*>} XML namespace. To be used
 * on {@link Configuration @Configuration} classes as follows:
 *
 * <pre class="code">
 * &#064;Configuration
 * &#064;EnableScheduling
 * public class AppConfig {
 *
 *     // various &#064;Bean definitions
 * }</pre>
 *
 * <p>This enables detection of {@link Scheduled @Scheduled} annotations on any
 * Spring-managed bean in the container. For example, given a class {@code MyTask}:
 *
 * <pre class="code">
 * package com.myco.tasks;
 *
 * public class MyTask {
 *
 *     &#064;Scheduled(fixedRate=1000)
 *     public void work() {
 *         // task execution logic
 *     }
 * }</pre>
 *
 * <p>the following configuration would ensure that {@code MyTask.work()} is called
 * once every 1000 ms:
 *
 * <pre class="code">
 * &#064;Configuration
 * &#064;EnableScheduling
 * public class AppConfig {
 *
 *     &#064;Bean
 *     public MyTask task() {
 *         return new MyTask();
 *     }
 * }</pre>
 *
 * <p>Alternatively, if {@code MyTask} were annotated with {@code @Component}, the
 * following configuration would ensure that its {@code @Scheduled} method is
 * invoked at the desired interval:
 *
 * <pre class="code">
 * &#064;Configuration
 * &#064;EnableScheduling
 * &#064;ComponentScan(basePackages="com.myco.tasks")
 * public class AppConfig {
 * }</pre>
 *
 * <p>Methods annotated with {@code @Scheduled} may even be declared directly within
 * {@code @Configuration} classes:
 *
 * <pre class="code">
 * &#064;Configuration
 * &#064;EnableScheduling
 * public class AppConfig {
 *
 *     &#064;Scheduled(fixedRate=1000)
 *     public void work() {
 *         // task execution logic
 *     }
 * }</pre>
 *
 * <p>By default, Spring will search for an associated scheduler definition: either
 * a unique {@link org.springframework.scheduling.TaskScheduler} bean in the context,
 * or a {@code TaskScheduler} bean named "taskScheduler" otherwise; the same lookup
 * will also be performed for a {@link java.util.concurrent.ScheduledExecutorService}
 * bean. If neither of the two is resolvable, a local single-threaded default
 * scheduler will be created and used within the registrar.
 *
 * <p>When more control is desired, a {@code @Configuration} class may implement
 * {@link SchedulingConfigurer}. This allows access to the underlying
 * {@link ScheduledTaskRegistrar} instance. For example, the following example
 * demonstrates how to customize the {@link Executor} used to execute scheduled
 * tasks:
 *
 * <pre class="code">
 * &#064;Configuration
 * &#064;EnableScheduling
 * public class AppConfig implements SchedulingConfigurer {
 *
 *     &#064;Override
 *     public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
 *         taskRegistrar.setScheduler(taskExecutor());
 *     }
 *
 *     &#064;Bean(destroyMethod="shutdown")
 *     public Executor taskExecutor() {
 *         return Executors.newScheduledThreadPool(100);
 *     }
 * }</pre>
 *
 * <p>Note in the example above the use of {@code @Bean(destroyMethod="shutdown")}.
 * This ensures that the task executor is properly shut down when the Spring
 * application context itself is closed.
 *
 * <p>Implementing {@code SchedulingConfigurer} also allows for fine-grained
 * control over task registration via the {@code ScheduledTaskRegistrar}.
 * For example, the following configures the execution of a particular bean
 * method per a custom {@code Trigger} implementation:
 *
 * <pre class="code">
 * &#064;Configuration
 * &#064;EnableScheduling
 * public class AppConfig implements SchedulingConfigurer {
 *
 *     &#064;Override
 *     public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
 *         taskRegistrar.setScheduler(taskScheduler());
 *         taskRegistrar.addTriggerTask(
 *             () -&gt; myTask().work(),
 *             new CustomTrigger()
 *         );
 *     }
 *
 *     &#064;Bean(destroyMethod="shutdown")
 *     public Executor taskScheduler() {
 *         return Executors.newScheduledThreadPool(42);
 *     }
 *
 *     &#064;Bean
 *     public MyTask myTask() {
 *         return new MyTask();
 *     }
 * }</pre>
 *
 * <p>For reference, the example above can be compared to the following Spring XML
 * configuration:
 *
 * <pre class="code">
 * &lt;beans&gt;
 *
 *     &lt;task:annotation-driven scheduler="taskScheduler"/&gt;
 *
 *     &lt;task:scheduler id="taskScheduler" pool-size="42"/&gt;
 *
 *     &lt;task:scheduled-tasks scheduler="taskScheduler"&gt;
 *         &lt;task:scheduled ref="myTask" method="work" fixed-rate="1000"/&gt;
 *     &lt;/task:scheduled-tasks&gt;
 *
 *     &lt;bean id="myTask" class="com.foo.MyTask"/&gt;
 *
 * &lt;/beans&gt;
 * </pre>
 *
 * <p>The examples are equivalent save that in XML a <em>fixed-rate</em> period is used
 * instead of a custom <em>{@code Trigger}</em> implementation; this is because the
 * {@code task:} namespace {@code scheduled} cannot easily expose such support. This is
 * but one demonstration how the code-based approach allows for maximum configurability
 * through direct access to the actual component.
 *
 * <p><b>Note: {@code @EnableScheduling} applies to its local application context only,
 * allowing for selective scheduling of beans at different levels.</b> Please redeclare
 * {@code @EnableScheduling} in each individual context, e.g. the common root web
 * application context and any separate {@code DispatcherServlet} application contexts,
 * if you need to apply its behavior at multiple levels.
 *
 * @author Chris Beams
 * @author Juergen Hoeller
 * @since 3.1
 * @see Scheduled
 * @see SchedulingConfiguration
 * @see SchedulingConfigurer
 * @see ScheduledTaskRegistrar
 * @see Trigger
 * @see ScheduledAnnotationBeanPostProcessor
 */
/**
 *启用Spring的计划任务执行功能，类似于
 *在Spring的{@code<task:*>}XML命名空间中找到的功能。待使用
 *关于｛@link Configuration@Configuration｝类，如下所示：
 *
 *<pre-class=“code”>
 *&#064；配置
 *&#064；启用调度
 *公共类AppConfig{
 *
 *//各种&#064；Bean定义
 *}</pre>
 *
 *<p>这允许在任何
 *Spring在容器中管理bean。例如，给定一个类｛@code MyTask｝：
 *
 *<pre-class=“code”>
 *包com.myc.tasks；
 *
 *公共类MyTask{
 *
 *&#064；计划（固定日期=1000）
 *公共无效工作（）{
 *//任务执行逻辑
 *}
 *}</pre>
 *
 *＜p＞以下配置将确保调用｛@code MyTask.work（）｝
 *每1000ms一次：
 *
 *<pre-class=“code”>
 *&#064；配置
 *&#064；启用调度
 *公共类AppConfig{
 *
 *&#064；豆
 *公共MyTask任务（）{
 *返回new MyTask（）；
 *}
 *}</pre>
 *
 *＜p＞或者，如果用｛@code@Component｝对｛@code MyTask｝进行了注释，则
 *以下配置将确保其｛@code@Scheduled｝方法
 *以所需的间隔调用：
 *
 *<pre-class=“code”>
 *&#064；配置
 *&#064；启用调度
 *&#064；组件扫描（basePackages=“com.myco.tasks”）
 *公共类AppConfig{
 *}</pre>
 *
 *＜p＞用｛@code@Scheduled｝注释的方法甚至可以直接在
 *｛@code@Configuration｝类：
 *
 *<pre-class=“code”>
 *&#064；配置
 *&#064；启用调度
 *公共类AppConfig{
 *
 *&#064；计划（固定日期=1000）
 *公共无效工作（）{
 *//任务执行逻辑
 *}
 *}</pre>
 *
 *＜p＞默认情况下，Spring将搜索相关联的调度程序定义：
 *上下文中唯一的{@linkorg.springframework.scheduling.TaskScheduler}bean，
 *或者一个名为“TaskScheduler”的{@code TaskScheduler}bean；相同的查找
 *还将为｛@link java.util.concurrent.ScheduledExecutiorService｝执行
 *豆。如果两者都不可解析，则本地单线程默认
 *调度器将在注册器中创建和使用。
 *
 *<p>当需要更多的控制时，｛@code@Configuration｝类可以实现
 *｛@link调度配置程序｝。这允许访问底层
 *｛@link ScheduledTaskRegistrar｝实例。例如，以下示例
 *演示如何自定义用于执行计划的｛@link Executor｝
 *任务：
 *
 *<pre-class=“code”>
 *&#064；配置
 *&#064；启用调度
 *公共类AppConfig实现SchedulingConfigurer{
 *
 *&#064；以（权力）否决
 *public void configureTasks（ScheduledTaskRegistrartaskRegistrar）{
 *taskRegistrar.setScheScheduler（taskExecutitor（））；
 *}
 *
 *&#064；Bean（destroyMethod=“关闭”）
 *公共执行程序taskExecutor（）{
 *return Executitors.newScheduledThreadPool（100）；
 *}
 *}</pre>
 *
 *<p>注意在上面的例子中使用了{@code@Bean（destroyMethod=“shutdown”）}。
 *这确保了当Spring
 *应用程序上下文本身是关闭的。
 *
 *＜p＞实现｛@code SchedulingConfigurer｝还允许细粒度
 *通过{@code ScheduledTaskRegistrar}控制任务注册。
 *例如，以下配置了特定bean的执行
 *每个自定义｛@code Trigger｝实现的方法：
 *
 *<pre-class=“code”>
 *&#064；配置
 *&#064；启用调度
 *公共类AppConfig实现SchedulingConfigurer{
 *
 *&#064；以（权力）否决
 *public void configureTasks（ScheduledTaskRegistrartaskRegistrar）{
 *taskRegistrar.setScheduler（taskScheduler（））；
 *任务注册器.addTriggerTask(
 *（）-&gt；myTask（）.work（），
 *新建自定义触发器（）
 *）；
 *}
 *
 *&#064；Bean（destroyMethod=“关闭”）
 *公共执行程序taskScheduler（）{
 *return Executitors.newScheduledThreadPool（42）；
 *}
 *
 *&#064；豆
 *公共MyTask MyTask（）{
 *返回new MyTask（）；
 *}
 *}</pre>
 *
 *＜p＞为了参考，上面的例子可以与下面的Spring XML进行比较
 *配置：
 *
 *<pre-class=“code”>
 *&lt；豆子&gt；
 *
 *&lt；任务：注释驱动的调度程序=“taskScheduler”/&gt；
 *
 *&lt；任务：调度程序id=“taskScheduler”池size=“42”/&gt；
 *
 *&lt；task:计划任务scheduler=“taskScheduler”&gt；
 *&lt；task:scheduled ref=“myTask”method=“work”固定费率=“1000”/&gt；
 *&lt/任务：计划任务&gt；
 *
 *&lt；bean id=“myTask”class=“com.foo.myTask”/&gt；
 *
 *&lt/豆子&gt；
 *</pre>
 *
 *<p>除了在XML中使用<em>固定利率</em>周期外，这些示例是等效的
 *而不是自定义的<em>｛@code Trigger｝</em>实现；这是因为
 *｛@code task:｝命名空间｛@code scheduled｝无法轻易公开此类支持。这是
 *但一个演示是基于代码的方法如何实现最大的可配置性
 *通过直接访问实际组件。
 *
 *<p><b>注意：｛@code@EnableScheduling｝仅适用于其本地应用程序上下文，
 *从而允许在不同级别上选择性地调度bean</b> 请重新申报
 *｛@code@EnableScheduling｝在每个单独的上下文中，例如公共根web
 *应用程序上下文和任何单独的{@code DispatcherServlet}应用程序上下文，
 *如果您需要在多个级别应用它的行为。
 *
 *@作者Chris Beams
 *@作者于尔根·霍勒
 *@自3.1起
 *@参见计划
 *@请参阅计划配置
 *@请参阅SchedulelingConfigurer
 *@见ScheduledTaskRegistrar
 *@参见触发器
 *@请参阅ScheduledAnnotationBeanPostProcessor
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Import(SchedulingConfiguration.class)
@Documented
public @interface EnableScheduling {

}
